﻿
#include "bsvmain_ui_analy.h"


#ifdef QTCN
#undef QTCN
#endif
#define QTCN(x) (x)

//判断字符串是否是数字
bool isNumber(const QString& v0)
{
	QString v = v0;  //备份一下

	if (v.count(".") > 1) return false;
	if (v.count("-") > 1) return false;
	if (v.indexOf("-") > 0) return false;

	int c1 = 0;
	int c2 = 0;
	bool is_num = true;

	if (v == "") return false;

	while (v.left(1) == "+") v = v.mid(1);

	for (int i = 0; i < v.length(); i++)
	{
		if ((v[i] < QChar('0') || v[i] > QChar('9')) && v[i] != QChar('.') && v[i] != QChar('-'))
		{
			is_num = false;
		}
	}

	c1 = v.count(".");
	c2 = v.count("-");

	if (c1 > 1) is_num = false;
	if (c2 > 1) is_num = false;

	int idx1 = v.indexOf(".-");
	int idx2 = v.indexOf("-.");
	int idx3 = v.indexOf("-");
	if (idx1 >= 0 || idx2 >= 0 || idx3 > 0) is_num = false;

	if (v.length() == 1 && v == "0") is_num = true;
	if (v.length() > 1 && v == "0") is_num = false;

	return is_num;
}


//去掉前面的tab与空格
void trimTabSpace(QString& v)
{
	//先取删除回车换行
	v.replace(QTCN("\r"), QTCN(""));
	v.replace(QTCN("\n"), QTCN(""));

	//再删除左边的\t\b
	QString lchr = v.left(1);
	while (lchr == QTCN("\t") || lchr == QTCN(" ") || lchr == QTCN("\a") || lchr == QTCN("\b") || lchr == QTCN("\f") || lchr == QTCN("\v"))
	{
		v = v.mid(1);
		lchr = v.left(1);
	}

	lchr = v.right(1);
	while (lchr == QTCN("\t") || lchr == QTCN(" ") || lchr == QTCN("\a") || lchr == QTCN("\b") || lchr == QTCN("\f") || lchr == QTCN("\v"))
	{
		int len = v.length();
		v = v.left(len - 1);
		lchr = v.right(1);
	}
}

//转义如\n\t\r等转成对应的字符
bool EscapeString(const QString& text, QString& value)
{
	QString vtxt = text;
	//vtxt是=号后面的字符串,把开头结尾的空格制表符等删除
	trimTabSpace(vtxt);
	//@用于取消转义字符
	if (vtxt.left(1) == QTCN("@"))
	{
		vtxt = vtxt.mid(1, -1);
		//处理引号问题
		int len = vtxt.length();
		if (vtxt.left(1) == QTCN("\"") && vtxt.right(1) == QTCN("\""))
			value = vtxt.mid(1, len - 2);
		else
			value = vtxt;

		return true;
	}

	//处理引号问题
	int len = vtxt.length();
	if (vtxt.left(1) == QTCN("\"") && vtxt.right(1) == QTCN("\""))
		value = vtxt.mid(1, len - 2);
	else
		value = vtxt;

	//转义字符处理
	//\"="
	value.replace(QTCN("\\\""), QTCN("\""));
	value.replace(QTCN("\\'"), QTCN("\'"));

	value.replace(QTCN("\\a"), QTCN("\a"));
	value.replace(QTCN("\\b"), QTCN("\b"));
	value.replace(QTCN("\\f"), QTCN("\f"));
	value.replace(QTCN("\\n"), QTCN("\n"));
	value.replace(QTCN("\\r"), QTCN("\r"));

	value.replace(QTCN("\\t"), QTCN("\t"));
	value.replace(QTCN("\\v"), QTCN("\v"));

	value.replace(QTCN("\\?"), QTCN("?"));

	value.replace(QTCN("\\x"), QTCN("\\X"));

	value.replace(QTCN("\\\\"), QTCN("\\"));
	value.replace(QTCN("\\0"), QTCN("\0"));

	int hex1 = value.indexOf(QTCN("\\X"));
	while (hex1 >= 0)
	{
		QString tmpValue = value.mid(hex1 + 2);
		int hex2 = tmpValue.indexOf(QTCN("\\X"));

		QString hexStr = value.mid(hex1 + 2, hex2);
		QByteArray hexBa = QByteArray::fromHex(hexStr.toUtf8());

		QString tmp1 = value.mid(0, hex1);
		QString tmp2 = tmpValue.mid(hex2);

		value = tmp1 + QString::fromUtf8(hexBa) + tmp2;

		hex1 = value.indexOf(QTCN("\\X"));
	}

	return true;
}

//直接转义
bool EscapeString(QString& text)
{
	QString vtxt = text;
	return EscapeString(vtxt, text);
}

//反转义
bool DeEscapeString(const QString& text, QString& value)
{
	value = text;

	int count = text.count();

	QString tmp;

	for (int i = 0; i < count; i++)
	{
		QChar c = text[i];

		     if (c == QTCN("\"")) tmp.append(QTCN("\\\""));
		else if (c == QTCN("'"))  tmp.append(QTCN("\\\'"));
		else if (c == QTCN("\a")) tmp.append(QTCN("\\a"));
		else if (c == QTCN("\b")) tmp.append(QTCN("\\b"));
		else if (c == QTCN("\f")) tmp.append(QTCN("\\f"));
		else if (c == QTCN("\n")) tmp.append(QTCN("\\n"));
		else if (c == QTCN("\r")) tmp.append(QTCN("\\r"));
		else if (c == QTCN("\t")) tmp.append(QTCN("\\t"));
		else if (c == QTCN("\v")) tmp.append(QTCN("\\v"));
		else if (c == QTCN("\?")) tmp.append(QTCN("\?"));
		else if (c == QTCN("\\")) tmp.append(QTCN("\\\\"));
		else tmp.append(c);
	}

	value = tmp;

	return true;
}


bool DeEscapeString(QString& text)
{
	QString value;
	DeEscapeString(text, value);
	text = value;
	return true;
}

//取出属性名与数据
bool getPropertyValue(const QString& text, QString& property, QString& value)
{
	int idx = text.indexOf(QTCN("="));
	if (idx < 0) return false;
	property = text.mid(0, idx);
	QString vtxt = text.mid(idx + 1);
	//vtxt是=号后面的字符串,把开头结尾的空格制表符等删除
	trimTabSpace(vtxt);
	//转义如\n\t\r等转成对应的字符
	return EscapeString(vtxt, value);
}

/*
	//@用于取消转义字符
	if (vtxt.left(1) == QTCN("@"))
	{
		vtxt = vtxt.mid(1, -1);
		//处理引号问题
		int len = vtxt.length();
		if (vtxt.left(1) == QTCN("\"") && vtxt.right(1) == QTCN("\""))
			value = vtxt.mid(1, len - 2);
		else
			value = vtxt;

		return true;
	}

	//处理引号问题
	int len = vtxt.length();
	if (vtxt.left(1) == QTCN("\"") && vtxt.right(1) == QTCN("\""))
		value = vtxt.mid(1, len - 2);
	else
		value = vtxt;

	//转义字符处理
	//\"="
	value.replace(QTCN("\\\""), QTCN("\""));
	value.replace(QTCN("\\'"), QTCN("\'"));

	value.replace(QTCN("\\a"), QTCN("\a"));
	value.replace(QTCN("\\b"), QTCN("\b"));
	value.replace(QTCN("\\f"), QTCN("\f"));
	value.replace(QTCN("\\n"), QTCN("\n"));
	value.replace(QTCN("\\r"), QTCN("\r"));

	value.replace(QTCN("\\t"), QTCN("\t"));
	value.replace(QTCN("\\v"), QTCN("\v"));

	value.replace(QTCN("\\?"), QTCN("?"));

	value.replace(QTCN("\\x"), QTCN("\\X"));

	int hex = value.indexOf(QTCN("\\X"));
	while (hex >= 0)
	{
		QString strHex = QTCN("");
		int len = value.length();
		for (int i = hex; i < len; i++)
		{
			int flag = 0;
			QString chr = value.mid(i + 2, 1);
			if (chr >= QTCN("0") && chr <= QTCN("9")) { flag = 1; strHex += chr; }
			if (chr >= QTCN("A") && chr <= QTCN("F")) { flag = 2; strHex += chr; }
			if (chr >= QTCN("a") && chr <= QTCN("f")) { flag = 3; strHex += chr; }
			if (flag == 0) break;
		}
		QByteArray ba = QByteArray::fromHex(strHex.toUtf8());
		value.replace("\\X" + strHex, QString::fromUtf8(ba));
		//循环查找16进制表达式
		hex = value.indexOf(QTCN("\\X"));
	}

	value.replace(QTCN("\\\\"), QTCN("\\"));
	value.replace(QTCN("\\0"), QTCN("\0"));

	if (value.left(1) == QTCN("\""))  value = value.mid(1);
	if (value.right(1) == QTCN("\"")) value = value.left(value.length() - 1);

	return true;
	*/

//type=0:Qt原生控件
//type=1:系统已有非图像窗口
//type=2:系统已有图像窗口
bool beginFlag(const QString& text, int& flag, int& type, QString& objName)
{
	flag = false;

	QString temp = text;
	temp = temp.replace(QTCN(" "), QTCN(""));
	temp = temp.replace(QTCN("\t"), QTCN(""));

	int idx = temp.indexOf(QTCN("BEGIN"));
	if (idx < 0) return false;
	QString ftxt = temp.mid(idx, 5);
	QString vtxt = temp.mid(5);
	flag = (ftxt == "BEGIN");

	int len = vtxt.length();
	QString lchr = vtxt.left(1);
	QString rchr = vtxt.right(1);
	if (lchr == QTCN("(") && rchr == QTCN(")"))
	{
		//已有窗口
		objName = vtxt.mid(1, len - 2);
		if (isNumber(objName))
			type = 2;
		else
			type = 1;
		return true;
	}
	else if (lchr == QTCN("[") && rchr == QTCN("]"))
	{
		//Qt原生控件
		type = 0;
		objName = vtxt.mid(1, len - 2);
		return true;
	}
	//不符合格式要求
	flag = false;
	return false;
}

//结带标志检测
bool endFlag(const QString& text)
{
	QString temp = text;
	temp = temp.replace(QTCN(" "), QTCN(""));
	temp = temp.replace(QTCN("\t"), QTCN(""));
	temp = temp.replace(QTCN("\a"), QTCN(""));
	temp = temp.replace(QTCN("\b"), QTCN(""));
	temp = temp.replace(QTCN("\f"), QTCN(""));
	temp = temp.replace(QTCN("\v"), QTCN(""));

	return temp == QTCN("END");
}

//转换成RECT类型
QRect toRect(QString r)
{
	return QRect(
		r.section(QTCN(","), 0, 0).toInt(),
		r.section(QTCN(","), 1, 1).toInt(),
		r.section(QTCN(","), 2, 2).toInt(),
		r.section(QTCN(","), 3, 3).toInt()
	);
}

QString toString(QRect r)
{
	QString rect =
		QString::number(r.left()) + "," +
		QString::number(r.top()) + "," +
		QString::number(r.width()) + "," +
		QString::number(r.height());
	return rect;
}

//字符串转换成longlong，支持16进制
unsigned long long string2ULongLong(const QString& text)
{
	if (text.left(2).toLower() == "0x")
	{
		QByteArray hex = text.mid(2).toUtf8();
		QByteArray ba = QByteArray::fromHex(hex);
		std::reverse(ba.begin(), ba.end());
		unsigned long long value = *(unsigned long long*)ba.data();
		return value;
	}
	else
	{
		unsigned long long value = text.toULongLong();
		return value;
	}
}

//字符串转数字，支持16进制
unsigned long string2ULong(const QString& text)
{
	if (text.left(2).toLower() == "0x")
	{
		QByteArray hex = text.mid(2).toUtf8();
		QByteArray ba = QByteArray::fromHex(hex);
		std::reverse(ba.begin(), ba.end());
		unsigned long value = *(unsigned long*)ba.data();
		return value;
	}
	else
	{
		unsigned long value = text.toULong();
		return value;
	}
}

//INC指令
bool includeFlag(const QString& text, QString& fileName)
{
	QString temp = text;
	temp = temp.replace(QTCN(" "), QTCN(""));
	temp = temp.replace(QTCN("\t"), QTCN(""));

	//查找的关键字
	QString findKey = QTCN("INC");
	int keyLen = findKey.length();

	int idx = temp.indexOf(findKey);
	if (idx < 0) return false;
	QString ftxt = temp.mid(idx, keyLen);
	QString vtxt = temp.mid(keyLen);
	bool flag = (ftxt == findKey);

	int len = vtxt.length();
	QString lchr = vtxt.left(1);
	QString rchr = vtxt.right(1);
	if (lchr == QTCN("(") && rchr == QTCN(")") && flag)
	{
		//已有窗口
		fileName = vtxt.mid(1, len - 2);
		//vtxt是=号后面的字符串,把开头结尾的空格制表符等删除
		trimTabSpace(fileName);
		//处理转义字符
		EscapeString(fileName);
		return true;
	}
	return false;
}


//检测是否是宏变量定义
bool checkMarcoVarDefine(const QString& cmdLine, QString& varName, QString& varValue)
{
	QString tmp = cmdLine;
	//宏定义一般有空格或\t
	int kg = tmp.indexOf(QTCN(" "));
	if (kg < 0)
	{
		kg = tmp.indexOf(QTCN("\t"));
	}
	//没有空也没有\t这不是宏定义
	if (kg < 0) return false;

	QString marcoFlag = tmp.mid(0, kg);
	if (marcoFlag == QTCN("VAR"))
	{
		tmp = tmp.mid(kg + 1);
		if (tmp == QTCN("")) return false;

		//读取一行，去除空格、tab、换行回车
		trimTabSpace(tmp);
		int dy = tmp.indexOf(QTCN("="));
		if (dy < 0)
		{
			//没有赋值
			varName = tmp.mid(0, dy);
			varValue = QTCN("");
		}
		else
		{
			//同时有赋值
			varName = tmp.mid(0, dy + 0);
			varValue= tmp.mid(dy + 1);
			//去掉空格与Tab字符等
			trimTabSpace(varValue);
			//处理转义字符
			EscapeString(varValue);
		}
		return true;
	}
	return false;
}


//替换命令行中的宏变量
bool replaceMarcoVarValue(QString& cmdLine, const QMap<QString,QString>& mcVarDef)
{
	int v1 = cmdLine.indexOf(QTCN("$("));
	int v2 = cmdLine.indexOf(QTCN(")"));

	if (v1 < 0)  return false;
	if (v2 < 0)  return false;
	if (v1 > v2) return false;

	while (true)
	{
		QString varName = cmdLine.mid(v1, v2 - v1 + 1);
		QString keyName = cmdLine.mid(v1 + 2, v2 - v1 - 2);
		QString replace = mcVarDef.value(keyName);
		//替换
		cmdLine.replace(varName, replace);

		v1 = cmdLine.indexOf(QTCN("$("));
		v2 = cmdLine.indexOf(QTCN(")"));

		if (v1 < 0 || v2 < 0 || v1 > v2) break;
	}

	//返回
	return true;
}
